﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Text.RegularExpressions;
using System.Web;
using System.Globalization;

namespace ChapterX.Common
{
    public class Utils
    {
        public static bool HasValue(String s)
        {
            return !String.IsNullOrEmpty(s) && !String.Empty.Equals(s.Trim());
        }

        // IMPORTANT: Test HasValue before Get!!!
        public static String GetValue(String s)
        {
            return s.Trim();
        }

        protected static bool NotDBNull(DataRow row, String columnName)
        {
            return row.Table.Columns.Contains(columnName) && row[columnName].GetType() != typeof(DBNull);
        }

        public static bool HasValue(DataRow row, String columnName)
        {
            return NotDBNull(row, columnName) && HasValue(row[columnName].ToString());
        }

        public static bool IsValidEmailAddress(String email)
        {
            bool result = false;

            if (HasValue(email))
            {
                String pattern = @"^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$";
                result = Regex.IsMatch(email, pattern, RegexOptions.IgnoreCase);
            }

            return result;
        }

        public static bool IsPlainText(String text)
        {
            bool result = false;

            if (HasValue(text))
            {
                String pattern = "<[^>]*?>";
                result = !Regex.IsMatch(text, pattern, RegexOptions.IgnoreCase);
            }
            else
            {
                result = (null != text); // Take empty string as valid.
            }

            return result;
        }

        public static String FilterHtml(String s)
        {
            s = Regex.Replace(s, "<[^>]*?>", String.Empty, RegexOptions.IgnoreCase | RegexOptions.Multiline);
            s = s.Replace("&nbsp;", " ");
            return s;
        }

        public static String FilterHtmlStrict(String s)
        {
            s = Regex.Replace(s, "<[^>]*?>", String.Empty, RegexOptions.IgnoreCase | RegexOptions.Multiline);
            s = s.Replace("&nbsp;", " ");
            return HttpUtility.HtmlEncode(s);
        }

        public static String FilterSql(String s)
        {
            return Regex.Replace(s, "[\'|\"]", String.Empty);
        }

        public static Object ChangeTypeEx(Object value, Type conversionType)
        {
            if (conversionType.Equals(typeof(Int32)))
            {
                int result;
                String s = value.ToString();
                if (Int32.TryParse(s, out result))
                {
                    return result;
                }
                else
                {
                    s = Regex.Replace(s, @"[^\d]", String.Empty);
                    if (Int32.TryParse(s, out result))
                    {
                        return result;
                    }
                    else
                    {
                        throw new ParseException("无法解析的整数类型");
                    }
                }
            }
            else
            {
                return Convert.ChangeType(value, conversionType);
            }
        }

        public static int ParseInt32(String s, int start, int end)
        {
            int n;
            if (Int32.TryParse(s, out n) && n >= start && n <= end)
            {
                return n;
            }
            else
            {
                throw new ParseException();
            }
        }

        public static int ParseInt32(String s, int start)
        {
            return ParseInt32(s, start, Int32.MaxValue);
        }

        public static decimal ParseDecimal(String s, decimal start)
        {
            decimal n;
            if (Decimal.TryParse(s, out n) && n >= start)
            {
                return n;
            }
            else
            {
                throw new ParseException();
            }
        }

        #region Beautify Title

        private static CultureInfo _enCultureInfo = null;

        protected static CultureInfo EnCultureInfo
        {
            get
            {
                if (null == _enCultureInfo)
                {
                    _enCultureInfo = CultureInfo.CreateSpecificCulture("en-US");
                }
                return _enCultureInfo;
            }
        }

        protected const String KeepLowerPattern = @"\W(a|an|and|as|at|by|for|from|in|of|on|or|the|to|with)(?=\W)";

        protected const String KeepUpperPattern = @"\W(ACM|IEEE|UML)(?=\W)";

        protected static String KeepLowerDelegate(Match m)
        {
            return m.Value.ToLower(EnCultureInfo);
        }

        protected static String KeepUpperDelegate(Match m)
        {
            return m.Value.ToUpper(EnCultureInfo);
        }

        protected static String KeepTitleCaseDelegate(Match m)
        {
            return EnCultureInfo.TextInfo.ToTitleCase(m.Value);
        }

        public static String BeautifyTitle(String s)
        {
            // 去掉多余的空格
            s = Regex.Replace(s, " +", " ");

            // 如果标题不包含字母字符，不继续处理
            if (!Regex.IsMatch(s, @"\w"))
            {
                return s;
            }

            // 保护“<”和“>”
            s = s.Replace('<', '(').Replace('>', ')');

            // 去掉头尾非字母字符
            s = Regex.Replace(s, @"^[^\w(（""]+|[^\w)）""!\?#]+$", String.Empty);

            // 美化标点符号
            s = Regex.Replace(s, @" *([,.:]) *", "$1 ");

            // ToTitleCase
            s = EnCultureInfo.TextInfo.ToTitleCase(s.ToLower());

            // 保持特定单词小写
            Regex keepLower = new Regex(KeepLowerPattern, RegexOptions.IgnoreCase);
            s = keepLower.Replace(s, new MatchEvaluator(KeepLowerDelegate));

            // 保持特定单词大写
            Regex keepUpper = new Regex(KeepUpperPattern, RegexOptions.IgnoreCase);
            s = keepUpper.Replace(s, new MatchEvaluator(KeepUpperDelegate));

            // 保持头部、冒号后单词的首字母大写
            s = Regex.Replace(s, @"^\w+|: *\w+", new MatchEvaluator(KeepTitleCaseDelegate), RegexOptions.IgnoreCase);

            return s;
        }

        #endregion
    }
}